package com.xunlai.infra.permission.business.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.xunlai.infra.permission.business.dao.entity.Member;
import com.xunlai.infra.permission.business.dao.entity.MembershipsGoods;
import com.xunlai.infra.permission.business.dao.entity.Order;
import com.xunlai.infra.permission.business.dao.entity.OrderGoods;
import com.xunlai.infra.permission.business.dao.repository.MemberRepository;
import com.xunlai.infra.permission.business.dao.repository.MembershipsGoodsRepository;
import com.xunlai.infra.permission.business.dao.repository.OrderGoodsRepository;
import com.xunlai.infra.permission.business.dao.repository.OrderRepository;
import com.xunlai.infra.permission.business.service.OrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;
import java.util.Optional;

/**
 * @author liang
 * @date 9/8/23 9:52 PM
 */
@Service
public class OrderServiceImpl implements OrderService {

    private final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);

    private MemberRepository memberRepository;

    private OrderRepository orderRepository;

    private OrderGoodsRepository orderGoodsRepository;

    private MembershipsGoodsRepository membershipsGoodsRepository;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void paySuccess(String orderNo) {
        Optional<Order> orderOptional = orderRepository.findByOrderNo(orderNo);
        if(orderOptional.isEmpty()){
            logger.error("订单支付成功，未查询到订单号："+orderNo);
            return;
        }
        Order order = orderOptional.get();
        order.setPayTime(LocalDateTime.now());
        order.setStatus(Order.OrderStatus.PAID.getStatus());
        Long customerId = order.getCustomerId();
        Optional<Member> memberOptional = memberRepository.findByAccountId(customerId);
        OrderGoods orderGoods = orderGoodsRepository.findByOrderId(order.getId());
        String goodsClass = orderGoods.getGoodsClass();
        Long goodsId = orderGoods.getGoodsId();
        MembershipsGoods membershipsGoods = null;
        if(MembershipsGoods.class.getSimpleName().equals(goodsClass) && orderGoods.getGoodsSnapshot() != null){
            String goodsSnapshot = orderGoods.getGoodsSnapshot();
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.registerModule(new JavaTimeModule());
            try {
                membershipsGoods = objectMapper.readValue(goodsSnapshot, MembershipsGoods.class);
            } catch (JsonProcessingException e) {
                logger.error(e.getMessage(),e);
            }
        }
        if(membershipsGoods == null){
            Optional<MembershipsGoods> membershipsGoodsOptional = membershipsGoodsRepository.findById(goodsId);
            if(membershipsGoodsOptional.isEmpty()){
                return;
            }
            membershipsGoods = membershipsGoodsOptional.get();
        }
        Integer timeLimit = membershipsGoods.getTimeLimit();
        Integer limitUnit = membershipsGoods.getLimitUnit();
        ChronoUnit unit = limitUnit == 0 ? ChronoUnit.YEARS : (limitUnit == 1 ? ChronoUnit.MONTHS : ChronoUnit.DAYS);
        Member member = memberOptional.orElse(null);
        if(member == null) {
            member = new Member();
            member.setVipLevel(1);
            member.setAccountId(customerId);
            LocalDateTime now = LocalDateTime.now();
            member.setVipStartTime(now);
            LocalDateTime end = now.plus(timeLimit, unit);
            member.setVipEndTime(end);
            memberRepository.save(member);
        }else {
            LocalDateTime vipStartTime = member.getVipStartTime();
            if(vipStartTime == null){
                LocalDateTime now = LocalDateTime.now();
                member.setVipStartTime(now);
                LocalDateTime end = now.plus(timeLimit, unit);
                member.setVipEndTime(end);
                memberRepository.save(member);
            }else {
                LocalDateTime vipEndTime = member.getVipEndTime();
                if(vipEndTime == null || vipEndTime.isBefore(LocalDateTime.now())){
                    //已过期，重新算
                    LocalDateTime now = LocalDateTime.now();
                    member.setVipStartTime(now);
                    LocalDateTime end = now.plus(timeLimit, unit);
                    member.setVipEndTime(end);
                    memberRepository.save(member);
                }else {
                    //续期
                    LocalDateTime end = vipEndTime.plus(timeLimit, unit);
                    member.setVipEndTime(end);
                    memberRepository.save(member);
                }
            }
        }
        order.setStatus(Order.OrderStatus.COMPLETE.getStatus());
        orderRepository.save(order);

    }

    public int orderStatus(Long orderId){
        Optional<Order> orderOptional = orderRepository.findById(orderId);
        if(orderOptional.isEmpty()){
            return -1;
        }
        return orderOptional.get().getStatus();
    }

    @Autowired
    public void setMemberRepository(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    @Autowired
    public void setOrderRepository(OrderRepository orderRepository) {
        this.orderRepository = orderRepository;
    }

    @Autowired
    public void setOrderGoodsRepository(OrderGoodsRepository orderGoodsRepository) {
        this.orderGoodsRepository = orderGoodsRepository;
    }

    @Autowired
    public void setMembershipsGoodsRepository(MembershipsGoodsRepository membershipsGoodsRepository) {
        this.membershipsGoodsRepository = membershipsGoodsRepository;
    }
}
